﻿using AutoMapper;
using SXICE.Core.Domains;
using SXICE.Core.Helpers;
using SXICE.Core.Models;
using SXICE.Core.Models.DTOs;
using SXICE.Core.Models.Search;
using SXICE.IRepository;
using SXICE.IService;
using SXICE.Service.Validators;
using SXICE.Service.Utilities;
using System.Collections.Generic;
using SXICE.IService.Models;

namespace SXICE.Service
{
    /// <summary>
    /// 医生服务
    /// </summary>
    public class DoctorService : IDoctorService
    {
        /// <summary>
        /// 映射接口
        /// </summary>
        private readonly IMapper mapper;
        /// <summary>
        /// 医生仓储接口
        /// </summary>
        private readonly IDoctorRepository doctorRepository;
        /// <summary>
        /// 医生验证器
        /// </summary>
        private readonly static DoctorValidator doctorValidator = new DoctorValidator();
        /// <summary>
        /// 记录查询验证器
        /// </summary>
        private readonly static RecordSearchValidator recordSearchValidator = new RecordSearchValidator();
        public DoctorService(IMapper mapper, IDoctorRepository doctorRepository)
        {
            this.mapper = mapper;
            this.doctorRepository = doctorRepository;
        }

        public ReturnResult<bool> Register(Doctor doctor)
        {
            if (!doctorValidator.Validate(doctor, out var error))
                return ServiceErrors.EAPESMAT_USERNAME_LENGTH_TOO_LONG.ToResult<bool>(error);
            doctor.Password = SecurityHelper.MD5Encryption(doctor.Password);
            if (doctorRepository.GetOneByName(doctor.UserName).Success)
                return ServiceErrors.USER_EXISTED.ToResult<bool>("此用户名已存在");
            var role = RuntimeHelper.Resolve<IRightsRepository>().GetRoleById(doctor.RoleId);
            if (!role.Success)
                return role.ToErrorResult<bool>();
            doctor.RoleName = role.Result.Name;
            return doctorRepository.InsertOne(doctor);
        }

        public ReturnResult<DoctorDTO> GetUser(DoctorDTO doctor)
        {
            var user = doctorRepository.GetOneByName(doctor.UserName);
            if (!user.Success)
                return user.ToErrorResult<DoctorDTO>();
            if (!user.Result.Enabled)
                return ServiceErrors.DOCTOR_DISABLED.ToResult<DoctorDTO>("此账号已被禁用");
            if (user.Result.Password == SecurityHelper.MD5Encryption(doctor.Password))
                return mapper.Map<ReturnResult<DoctorDTO>>(user);
            return ServiceErrors.PASSWORD_NOT_EQUALS.ToResult<DoctorDTO>("密码错误");
        }

        public ReturnPageListResult<DoctorDTO> Search(PageListQuery<RecordSearchModel> pageListQuery)
        {
            if (!recordSearchValidator.Validate(pageListQuery.Condition, out var error))
                return ServiceErrors.EAPESMAT_USERNAME_LENGTH_TOO_LONG.ToPageResult<DoctorDTO>(error);
            return mapper.Map<ReturnPageListResult<DoctorDTO>>(doctorRepository.Search(pageListQuery));
        }

        public ReturnResult<DoctorDTO> GetOneById(int id)
        {
            var user = doctorRepository.GetOneById(id);
            return mapper.Map<ReturnResult<DoctorDTO>>(user);
        }

        public ReturnResult<bool> Update(Doctor doctor)
        {
            var fields = new List<string> { nameof(doctor.RealName) };
            if (!doctor.Password.IsNullOrEmpty())
                fields.Add(nameof(doctor.Password));
            if (!doctorValidator.Validate(doctor, out var error, fields.ToArray()))
                return ErrorCode.MODEL_ERROR.ToResult<bool>(error);
            if (!doctor.Password.IsNullOrEmpty())
                doctor.Password = SecurityHelper.MD5Encryption(doctor.Password);
            return doctorRepository.UpdateObject(doctor);
        }

        public ReturnResult<bool> Delete(int id, bool state)
        {
            var doctor = doctorRepository.GetOneById(id);
            if (!doctor.Success)
                return doctor.ToErrorResult<bool>();
            return doctorRepository.DeleteDoctor(id, state);
        }

        public ReturnResult<bool> UpdateRole(Doctor doctor)
        {
            var role = RuntimeHelper.Resolve<IRightsRepository>().GetRoleById(doctor.RoleId);
            if (!role.Success)
                return role.ToErrorResult<bool>();
            doctor.RoleName = role.Result.Name;
            return doctorRepository.UpdateRole(doctor);
        }

        public ReturnResult<bool> UpdatePassword(ChangePasswordDTO changePasswordDTO)
        {
            var doctor = mapper.Map<Doctor>(changePasswordDTO);
            if (!doctorValidator.Validate(doctor, out var error, nameof(doctor.Password)))
                return ErrorCode.MODEL_ERROR.ToResult<bool>(error);
            var doctorResult = doctorRepository.GetOneById(changePasswordDTO.Id);
            if (!doctorResult.Success)
                return doctorResult.ToErrorResult<bool>();
            doctor.RealName = SecurityHelper.MD5Encryption(doctor.RealName);
            doctor.Password = SecurityHelper.MD5Encryption(doctor.Password);
            if (doctor.RealName != doctorResult.Result.Password)
                return ServiceErrors.PASSWORD_NOT_EQUALS.ToResult<bool>("旧密码不正确");
            return doctorRepository.UpdatePassword(doctor);
        }

        public ReturnResult IsEnabled(int id)
        {
            return doctorRepository.IsEnabled(id);
        }
    }
}
